package edu.csl.study.mybatis.plus.codegenerator;


import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class CodeGenerator {

    public static final String DB_DriverName = "com.mysql.cj.jdbc.Driver";
    //public static final String DB_URL = "jdbc:mysql://localhost:3306/study_basic?useUnicode=true&useSSL=false&characterEncoding=utf8";
    public static final String DB_URL = "jdbc:mysql://localhost:3306/xiandai_prpcar_uat_online?useUnicode=true&useSSL=false&characterEncoding=utf8";
    public static final String DB_USENAME = "root";
    public static final String DB_PASSWORD = "admin";

    public static final String Parent_Package_DIR = "edu.csl.study.springboot.core";
    //生成的代码位置
    public static String  Project_Path = System.getProperty("user.dir");
    //XML文件是在java的mapper/xml文件夹下，还是在 resouces/mapper/模块名
    public static final  boolean  MapperXML_In_Resources= false;

    public static void main(String[] args) throws IOException {
        Project_Path ="D:\\workspace\\EclipseSpace\\2021\\SpringBoot";
        generate("dcode");
    }

    public static void generate(String modelName) throws IOException {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        //全局配置
        configGlobal(mpg);
        //数据源配置
        configDataSource(mpg);
        //包配置
        configPackage(mpg,modelName);
        //配置策略
        configStrategy(mpg,modelName);
        configTemplate(mpg);
        cofnigCustom(mpg);
        mpg.execute();
    }
    /**
     * 进行全局配置
     * @param generator :
     */
    private static void configGlobal(AutoGenerator generator) {

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(Project_Path + "/src/main/java");
        gc.setAuthor("自动生成代码");
        gc.setOpen(false);
        //是否覆盖生成过的已有文件
        gc.setFileOverride(true);
        // XML文件返回对象定义ResultMap
        gc.setBaseResultMap(true);
        // XML返回对象字段列表columList
        gc.setBaseColumnList(true);
        //开启 swagger2 模式,实体属性 Swagger2 注解,默认false
        gc.setSwagger2(true);

        generator.setGlobalConfig(gc);

    }
    private static void configDataSource(AutoGenerator generator) {
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl(DB_URL);
        dsc.setDriverName(DB_DriverName);
        dsc.setUsername(DB_USENAME);
        dsc.setPassword(DB_PASSWORD);
        generator.setDataSource(dsc);
    }
    /**
     * 各个包配置
     * @param generator :
     */
    private static void configPackage(AutoGenerator generator,String modelName) {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(modelName);
        packageConfig.setParent(Parent_Package_DIR);//包路径
        packageConfig.setController("controller");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setEntity("entity");
        packageConfig.setMapper("mapper");
        packageConfig.setXml("mapper.xml");
        generator.setPackageInfo(packageConfig);
    }
    /**
     * 策略配置
     * @param generator :
     */
    private static void configStrategy(AutoGenerator generator,String modelName) throws IOException {
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //全局大写命名
        //strategy.setCapitalMode(true)
        //全局下划线命名
        //strategy.setDbColumnUnderline(true)
        //表的前缀
        //strategy.setTablePrefix(PREFIX);

        //表名下划线转为驼峰
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //字段名下划线转为驼峰
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //你自己的父类实体,没有就不用设置!
        strategy.setSuperEntityClass("");

        //是否使用lombok
        strategy.setEntityLombokModel(true);
        //设置是否restful控制器
        strategy.setRestControllerStyle(true);
        //设置布尔类型字段是否去掉is前缀
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);

        // 公共父类 你自己的父类控制器,没有就不用设置!
        strategy.setSuperControllerClass("");
        // 写于父类中的公共字段
        strategy.setSuperEntityColumns("");
        //使用的表，在table文件夹下定义
        String[] tableArray = readFile(modelName);
        strategy.setInclude(tableArray);
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix("");
        generator.setStrategy(strategy);
        //设置模版引擎的类型 freemarker使用ftl文件，velocity使用vm文件
        generator.setTemplateEngine(new FreemarkerTemplateEngine());
        // generator.setTemplateEngine(new VelocityTemplateEngine());
    }
    /**
     * 模版引擎配置
     * @param generator :
     */
    private static void configTemplate(AutoGenerator generator) {
        //模板引擎配置 默认是VelocityTemplateEngine
        TemplateConfig templateConfig = new TemplateConfig();
        if(MapperXML_In_Resources){
            templateConfig.setXml(null);
        }
        generator.setTemplate(templateConfig);
    }
    /**
     * 自定义配置
     * @param generator :
     */
    private static void cofnigCustom(AutoGenerator generator) {
        if(!MapperXML_In_Resources){
            return;
        }
        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();

        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
                return Project_Path + "/src/main/resources/mapper/" + generator.getPackageInfo().getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
       /*
        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判断自定义文件夹是否需要创建
                checkDir("调用默认方法创建的目录，自定义目录用");
                if (fileType == FileType.MAPPER) {
                    // 已经生成 mapper 文件判断存在，不想重新生成返回 false
                    return !new File(filePath).exists();
                }
                // 允许生成模板文件
                return true;
            }
        });
        */
        cfg.setFileOutConfigList(focList);
        generator.setCfg(cfg);


    }



    /**
     * 读取txt文件当中的数据表，要求：文件名称定义成和包dao、vo、po的上层包名一样
     * @param muduleName
     * @return
     * @throws UnsupportedEncodingException
     * @throws Exception
     */
    public static String[]  readFile (String muduleName) throws FileNotFoundException, IOException, UnsupportedEncodingException {

        List<String>  list = new ArrayList<String>();

        InputStream ins = CodeGenerator.class.getClassLoader().getResourceAsStream("table/"+muduleName+".txt") ;//考虑到编码格式


        System.out.println("table/"+muduleName+".txt");


        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(ins));

        String lineTxt = null;

        while((lineTxt = bufferedReader.readLine()) != null){

            list.add(lineTxt);
        }
        ins.close();
        //转换成数组
        String[] tableArray=new String[list.size()];
        for(int i=0;i<list.size();i++){
            tableArray[i]=list.get(i);
        }
        System.out.println(list.size()+"个数据表："+list.toString());
        return tableArray;
    }

}
